import tkinter as tk
from tkinter import ttk, messagebox, simpledialog
import time
import threading
import winsound  # Windows系统声音
import platform
import os
from datetime import datetime
import json  # 新增导入

class PomodoroTimer:
    def __init__(self, root):
        self.root = root
        self.root.title("番茄闹钟 - Pomodoro Timer")
        self.root.geometry("400x650+800+200")
        self.root.resizable(False, False)
        
        # 设置窗口图标和样式
        self.root.configure(bg='#2C3E50')
        
        # 计时器状态
        self.is_running = False
        self.is_paused = False
        self.is_break = False
        self.time_left = 25 * 60  # 默认25分钟
        self.total_time = 25 * 60
        
        # 统计数据
        self.pomodoro_count = 0
        self.total_work_time = 0
        self.session_start_time = None
        
        # 时间设置（分钟）
        self.work_duration = 25
        self.short_break = 5
        self.long_break = 15
        
        # 记录存储
        self.records_file = "pomodoro_records.json"
        self.records = []
        self.load_records()
        
        self.setup_ui()
        self.update_display()
        
    def load_records(self):
        """加载存储的记录"""
        try:
            if os.path.exists(self.records_file):
                with open(self.records_file, 'r', encoding='utf-8') as f:
                    self.records = json.load(f).get('records', [])
        except Exception as e:
            print(f"加载记录失败: {e}")
            self.records = []
            
    def save_records(self):
        """保存记录到文件"""
        try:
            with open(self.records_file, 'w', encoding='utf-8') as f:
                json.dump({'records': self.records}, f, ensure_ascii=False, indent=2)
        except Exception as e:
            print(f"保存记录失败: {e}")
        
    def setup_ui(self):
        # 标题
        title_frame = tk.Frame(self.root, bg='#2C3E50')
        title_frame.pack(pady=20)
        
        title_label = tk.Label(
            title_frame, 
            text="🍅 番茄闹钟", 
            font=("Arial", 24, "bold"),
            fg='#ECF0F1',
            bg='#2C3E50'
        )
        title_label.pack()
        
        # 状态显示
        self.status_label = tk.Label(
            self.root,
            text="工作时间",
            font=("Arial", 14),
            fg='#3498DB',
            bg='#2C3E50'
        )
        self.status_label.pack(pady=5)
        
        # 时间显示
        self.time_label = tk.Label(
            self.root,
            text="25:00",
            font=("Digital-7", 72, "bold"),
            fg='#E74C3C',
            bg='#2C3E50'
        )
        self.time_label.pack(pady=20)
        
        # 进度条
        self.progress = ttk.Progressbar(
            self.root,
            length=300,
            mode='determinate',
            style="TProgressbar"
        )
        self.progress.pack(pady=10)
        
        # 统计信息
        stats_frame = tk.Frame(self.root, bg='#34495E')
        stats_frame.pack(pady=10, padx=20, fill='x')
        
        self.pomodoro_label = tk.Label(
            stats_frame,
            text=f"完成番茄: {self.pomodoro_count}",
            font=("Arial", 12),
            fg='#ECF0F1',
            bg='#34495E'
        )
        self.pomodoro_label.pack(side='left', padx=20, pady=5)
        
        self.total_time_label = tk.Label(
            stats_frame,
            text=f"总工作时间: {self.total_work_time}分钟",
            font=("Arial", 12),
            fg='#ECF0F1',
            bg='#34495E'
        )
        self.total_time_label.pack(side='right', padx=20, pady=5)
        
        # 控制按钮
        button_frame = tk.Frame(self.root, bg='#2C3E50')
        button_frame.pack(pady=20)
        
        self.start_button = tk.Button(
            button_frame,
            text="开始",
            command=self.start_timer,
            font=("Arial", 12),
            bg='#27AE60',
            fg='white',
            width=8,
            height=2,
            relief='flat',
            cursor='hand2'
        )
        self.start_button.grid(row=0, column=0, padx=5)
        
        self.pause_button = tk.Button(
            button_frame,
            text="暂停",
            command=self.pause_timer,
            font=("Arial", 12),
            bg='#F39C12',
            fg='white',
            width=8,
            height=2,
            relief='flat',
            cursor='hand2',
            state='disabled'
        )
        self.pause_button.grid(row=0, column=1, padx=5)
        
        self.reset_button = tk.Button(
            button_frame,
            text="重置",
            command=self.reset_timer,
            font=("Arial", 12),
            bg='#E74C3C',
            fg='white',
            width=8,
            height=2,
            relief='flat',
            cursor='hand2'
        )
        self.reset_button.grid(row=0, column=2, padx=5)
        
        # 查看记录按钮
        self.view_records_button = tk.Button(
            button_frame,
            text="查看记录",
            command=self.view_records,
            font=("Arial", 12),
            bg='#3498DB',
            fg='white',
            width=8,
            height=2,
            relief='flat',
            cursor='hand2'
        )
        self.view_records_button.grid(row=0, column=3, padx=5, pady=5)
        
        # 设置区域
        settings_frame = tk.LabelFrame(
            self.root,
            text="时间设置（分钟）",
            font=("Arial", 10),
            fg='#ECF0F1',
            bg='#34495E'
        )
        settings_frame.pack(pady=10, padx=20, fill='x')
        
        # 工作时间设置
        work_frame = tk.Frame(settings_frame, bg='#34495E')
        work_frame.pack(pady=5)
        
        tk.Label(
            work_frame,
            text="工作时间:",
            font=("Arial", 10),
            fg='#ECF0F1',
            bg='#34495E'
        ).pack(side='left', padx=5)
        
        self.work_var = tk.StringVar(value="25")
        work_spinbox = tk.Spinbox(
            work_frame,
            from_=1,
            to=60,
            textvariable=self.work_var,
            width=5,
            font=("Arial", 10)
        )
        work_spinbox.pack(side='left')
        
        # 短休息设置
        short_break_frame = tk.Frame(settings_frame, bg='#34495E')
        short_break_frame.pack(pady=5)
        
        tk.Label(
            short_break_frame,
            text="短休息:",
            font=("Arial", 10),
            fg='#ECF0F1',
            bg='#34495E'
        ).pack(side='left', padx=5)
        
        self.short_break_var = tk.StringVar(value="5")
        short_break_spinbox = tk.Spinbox(
            short_break_frame,
            from_=1,
            to=30,
            textvariable=self.short_break_var,
            width=5,
            font=("Arial", 10)
        )
        short_break_spinbox.pack(side='left')
        
        # 长休息设置
        long_break_frame = tk.Frame(settings_frame, bg='#34495E')
        long_break_frame.pack(pady=5)
        
        tk.Label(
            long_break_frame,
            text="长休息:",
            font=("Arial", 10),
            fg='#ECF0F1',
            bg='#34495E'
        ).pack(side='left', padx=5)
        
        self.long_break_var = tk.StringVar(value="15")
        long_break_spinbox = tk.Spinbox(
            long_break_frame,
            from_=1,
            to=60,
            textvariable=self.long_break_var,
            width=5,
            font=("Arial", 10)
        )
        long_break_spinbox.pack(side='left')
        
        # 应用设置按钮
        apply_button = tk.Button(
            settings_frame,
            text="应用设置",
            command=self.apply_settings,
            font=("Arial", 10),
            bg='#3498DB',
            fg='white',
            relief='flat',
            cursor='hand2'
        )
        apply_button.pack(pady=5)
        
        # 设置进度条样式
        style = ttk.Style()
        style.theme_use('default')
        style.configure(
            "TProgressbar",
            background='#3498DB',
            troughcolor='#2C3E50',
            bordercolor='#2C3E50',
            lightcolor='#3498DB',
            darkcolor='#3498DB'
        )
        
    def apply_settings(self):
        """应用新的时间设置"""
        try:
            self.work_duration = int(self.work_var.get())
            self.short_break = int(self.short_break_var.get())
            self.long_break = int(self.long_break_var.get())
            
            if not self.is_running:
                self.time_left = self.work_duration * 60
                self.total_time = self.work_duration * 60
                self.update_display()
            
            messagebox.showinfo("设置成功", "时间设置已更新！")
        except ValueError:
            messagebox.showerror("错误", "请输入有效的数字！")
    
    def start_timer(self):
        """开始计时"""
        if not self.is_running:
            self.is_running = True
            self.is_paused = False
            self.start_button.config(state='disabled')
            self.pause_button.config(state='normal')
            
            if self.session_start_time is None:
                self.session_start_time = datetime.now()
            
            # 在新线程中运行计时器
            timer_thread = threading.Thread(target=self.run_timer)
            timer_thread.daemon = True
            timer_thread.start()
    
    def pause_timer(self):
        """暂停/继续计时"""
        if self.is_running:
            if self.is_paused:
                self.is_paused = False
                self.pause_button.config(text="暂停")
                timer_thread = threading.Thread(target=self.run_timer)
                timer_thread.daemon = True
                timer_thread.start()
            else:
                self.is_paused = True
                self.pause_button.config(text="继续")
    
    def reset_timer(self):
        """重置计时器"""
        self.is_running = False
        self.is_paused = False
        self.is_break = False
        
        if self.is_break:
            self.time_left = self.short_break * 60
            self.total_time = self.short_break * 60
        else:
            self.time_left = self.work_duration * 60
            self.total_time = self.work_duration * 60
        
        self.start_button.config(state='normal')
        self.pause_button.config(state='disabled', text="暂停")
        self.update_display()
    
    def run_timer(self):
        """运行计时器"""
        while self.is_running and self.time_left > 0 and not self.is_paused:
            time.sleep(1)
            if not self.is_paused:
                self.time_left -= 1
                self.root.after(0, self.update_display)
        
        if self.time_left == 0 and self.is_running:
            self.root.after(0, self.timer_complete)
    
    def timer_complete(self):
        """计时完成"""
        self.is_running = False
        self.play_sound()
        
        if not self.is_break:
            # 工作时间结束，进入休息
            self.pomodoro_count += 1
            self.total_work_time += self.work_duration
            
            # 添加工作记录
            note = self.get_note("工作")
            if note is not None:
                self.add_record(
                    type="work",
                    duration=self.work_duration,
                    note=note
                )
            
            # 检查是否需要长休息（每4个番茄钟）
            if self.pomodoro_count % 4 == 0:
                self.time_left = self.long_break * 60
                self.total_time = self.long_break * 60
                #messagebox.showinfo("休息时间", f"完成了{self.pomodoro_count}个番茄钟！\n长休息时间：{self.long_break}分钟")
            else:
                self.time_left = self.short_break * 60
                self.total_time = self.short_break * 60
                #messagebox.showinfo("休息时间", f"完成了第{self.pomodoro_count}个番茄钟！\n短休息时间：{self.short_break}分钟")
            
            self.is_break = True
            self.status_label.config(text="休息时间", fg='#27AE60')
            self.time_label.config(fg='#27AE60')
        else:
            # 休息时间结束，开始工作
            self.time_left = self.work_duration * 60
            self.total_time = self.work_duration * 60
            self.is_break = False
            self.status_label.config(text="工作时间", fg='#3498DB')
            self.time_label.config(fg='#E74C3C')
            
            # 添加休息记录
            note = self.get_note("休息")
            if note is not None:
                self.add_record(
                    type="break",
                    duration=self.short_break if self.pomodoro_count % 4 != 0 else self.long_break,
                    note=note
                )
            
            #messagebox.showinfo("工作提醒", "休息结束！开始新的番茄钟吧！")
        
        self.start_button.config(state='normal')
        self.pause_button.config(state='disabled', text="暂停")
        self.update_display()
    
    def update_display(self):
        """更新显示"""
        minutes = self.time_left // 60
        seconds = self.time_left % 60
        time_str = f"{minutes:02d}:{seconds:02d}"
        self.time_label.config(text=time_str)
        
        # 更新进度条
        if self.total_time > 0:
            progress_value = (1 - self.time_left / self.total_time) * 100
            self.progress['value'] = progress_value
        
        # 更新统计信息
        self.pomodoro_label.config(text=f"完成番茄: {self.pomodoro_count}")
        self.total_time_label.config(text=f"总工作时间: {self.total_work_time}分钟")
    
    def play_sound(self):
        """播放提示音"""
        try:
            if platform.system() == 'Windows':
                # Windows系统播放系统声音
                winsound.MessageBeep(winsound.MB_ICONEXCLAMATION)
                time.sleep(0.5)
                winsound.MessageBeep(winsound.MB_ICONEXCLAMATION)
            else:
                # 其他系统使用终端铃声
                print('\a\a\a')
        except:
            # 如果播放失败，静默处理
            pass
            
    def get_note(self, record_type):
        """获取用户输入的备注"""
        dialog = tk.Toplevel(self.root)
        dialog.title("添加备注")
        dialog.geometry("400x220+800+200")  # 设置窗口大小
        dialog.resizable(True, True)  # 允许调整大小
        dialog.attributes('-topmost',True)  # 窗口保持在最上层
        
        # 设置窗口居中
        dialog.transient(self.root)
        dialog.grab_set()
        
        result = {"note": None}
        
        # 创建标签
        label = ttk.Label(
            dialog, 
            text=f"为本次【{record_type}】添加备注(可选):",
            font=("Arial", 11)
        )
        label.pack(pady=20, padx=20)
        
        # 创建文本输入框
        text_entry = tk.Text(dialog, height=5, width=40, font=("Arial", 10))
        text_entry.pack(pady=10, padx=20)
        text_entry.focus_set()
        
        def on_ok():
            result["note"] = text_entry.get("1.0", tk.END).strip()
            dialog.destroy()
        
        def on_cancel():
            dialog.destroy()
        
        # 创建按钮框架
        button_frame = ttk.Frame(dialog)
        button_frame.pack(pady=10)
        
        ok_button = ttk.Button(button_frame, text="确定", command=on_ok, width=10)
        ok_button.pack(side=tk.LEFT, padx=5)
        
        cancel_button = ttk.Button(button_frame, text="取消", command=on_cancel, width=10)
        cancel_button.pack(side=tk.LEFT, padx=5)
        
        # 绑定回车键
        dialog.bind('<Return>', lambda e: on_ok())
        dialog.bind('<Escape>', lambda e: on_cancel())
        
        # 等待对话框关闭
        dialog.wait_window()
        
        return result["note"]
        
    def add_record(self, type, duration, note=""):
        """添加一条新记录"""
        record = {
            "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            "type": type,
            "duration": duration,
            "note": note
        }
        self.records.append(record)
        self.save_records()
        
    def view_records(self):
        """查看所有记录"""
        records_window = tk.Toplevel(self.root)
        records_window.title("番茄钟记录")
        records_window.geometry("600x400")
        records_window.resizable(True, True)
        
        # 创建滚动条
        scrollbar = ttk.Scrollbar(records_window)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        
        # 创建Treeview
        tree = ttk.Treeview(
            records_window,
            columns=("timestamp", "type", "duration", "note"),
            show="headings",
            yscrollcommand=scrollbar.set
        )
        tree.pack(fill=tk.BOTH, expand=True)
        
        # 配置列
        tree.heading("timestamp", text="时间")
        tree.heading("type", text="类型")
        tree.heading("duration", text="时长(分钟)")
        tree.heading("note", text="备注")
        
        tree.column("timestamp", width=150)
        tree.column("type", width=80)
        tree.column("duration", width=80)
        tree.column("note", width=290)
        
        # 添加数据
        for record in reversed(self.records):  # 最新记录显示在最上面
            tree.insert("", tk.END, values=(
                record["timestamp"],
                "工作" if record["type"] == "work" else "休息",
                record["duration"],
                record["note"]
            ))
        
        # 配置滚动条
        scrollbar.config(command=tree.yview)

def main():
    root = tk.Tk()
    app = PomodoroTimer(root)
    root.mainloop()

if __name__ == "__main__":
    main()
